#ifndef __THREAD_HPP__
#define __THREAD_HPP__

#include <iostream>
#include <string>
#include <unistd.h>
#include <functional>
#include <pthread.h>

namespace ThreadModule
{
    template<class T>
    using func_t = std::function<void(T)>;

    template <typename T>
    class Thread
    {
    public:
       
    public:
    Thread(std::string threadname, func_t<T> func, T data)
        :_threadname(threadname),_func(func),_data(data),_stop(true)
        {}

    void Excute()
    {
        _func(_data);
    }

    static void* funrutine(void* args)
    {
        Thread<T>* td = static_cast<Thread<T>*> (args);
        td->Excute();
        return nullptr;
    }

    bool Start()
    {   
        int n = pthread_create(&_tid, nullptr,funrutine, this);
        if(!n)
        {
            _stop = false;
            return true;
        }
        else return false;
    }

    std::string Name()
    {
        return _threadname;
    }

    void Join()
    {
        if(!_stop)
            pthread_join(_tid,nullptr);
    }

    void Detach()
    {
        if(!_stop)
            pthread_detach(_tid);
    }

    void Stop()
    {
        _stop = true;
    }

    ~Thread()
    {}
      

    private:
        std::string _threadname;
        func_t<T> _func;
        T _data;
        pthread_t _tid;
        bool _stop;
    };
} // namespace ThreadModule

#endif